
#include <stdatomic.h>

struct cond_t { 
	atomic_flag flag; 
	// 用于记录在当前条件变量上等待的线程数量
	int num_waiting;
	// 用于存放等待当前条件的线程的队列
	queue_t wait_queue;
};

void cond_init(cond_t *cond) {
	cond->num_waiting = 0;
	queue_init(cond->wait_queue);
}

void cond_wait(cond_t *cond, pthread_mutex_t *lock) {	
	while (atomic_flag_test_and_set(&cond->flag)) // TEST the flag
	;
	cond->num_waiting++;
	// 伪代码。模拟将当前线程加入到条件变量的等待队列
	queue_add(cond->wait_queue, get_currend_thread());
	
	// 释放管程的锁，让其他线程可以进入管程
	pthread_mutex_unlock(lock);
	
	// 伪代码，阻塞当前线程，相当于调用 schedule()
	park();
	
	// 一旦线程被唤醒，那么需要重新去抢管程的锁
	pthread_mutex_lock(lock);
	
	atomic_flag_clear(&cond->flag);
}

void cond_signal(cond_t *cond) {
	while (atomic_flag_test_and_set(&cond->flag)) // TEST the flag
    ; 
	if (cond->num_waiting > 0) {
		// 伪代码，从等待队列中拿出队头的等待线程 t
		pthread t = queue_remove(&cond->wait_queue);
		// 伪代码，唤醒这个线程
		unpark(t);
		cond->num_waiting--;
	}
	atomic_flag_clear(&cond->flag);
}






